package com.zhang.serviceorder.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhang.internalcommon.constant.CommonStatusEnum;
import com.zhang.internalcommon.constant.IdentityConstant;
import com.zhang.internalcommon.constant.OrderConstants;
import com.zhang.internalcommon.dto.*;
import com.zhang.internalcommon.response.OrderDriverResponse;
import com.zhang.internalcommon.response.TerminalResponse;
import com.zhang.internalcommon.response.TrsearchResponse;
import com.zhang.internalcommon.utils.RedisPrefixUtils;
import com.zhang.serviceorder.mapper.OrderInfoMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhang.serviceorder.remote.ServiceDriverUserClient;
import com.zhang.serviceorder.remote.ServiceMapClient;
import com.zhang.serviceorder.remote.ServicePriceClient;
import com.zhang.serviceorder.remote.ServiceSsePushClient;
import com.zhang.serviceorder.service.OrderInfoService;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 张开琦
 * @since 2025-04-16
 */
@Service
@Slf4j
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {
	@Autowired
	private OrderInfoMapper orderInfoMapper;

	@Autowired
	private ServicePriceClient servicePriceClient;

	@Autowired
	private StringRedisTemplate redisTemplate;

	@Autowired
	private ServiceDriverUserClient serviceDriverUserClient;

	@Autowired
	private ServiceMapClient serviceMapClient;

	@Autowired
	RedissonClient redissonClient;

	@Autowired
	ServiceSsePushClient serviceSsePushClient;

	/**
	 * 创建订单
	 *
	 * @param orderRequest
	 * @return
	 */
	@Override
	public ResponseResult addOrder(OrderRequest orderRequest) {

		// 测试当前城市是否有可用的司机
		ResponseResult<Boolean> availableDriver = serviceDriverUserClient.isAvailableDriver(orderRequest.getAddress());
		if (!availableDriver.getData()) {
			return ResponseResult.fail(CommonStatusEnum.CITY_DRIVER_EMPTY.getCode(), CommonStatusEnum.CITY_DRIVER_EMPTY.getValue());
		}

		// 判断计价规则版本是否是最新
		PriceRuleIsNewRequest priceRuleIsNewRequest = new PriceRuleIsNewRequest();
		priceRuleIsNewRequest.setFareType(orderRequest.getFareType());
		priceRuleIsNewRequest.setFareVersion(orderRequest.getFareVersion());
		ResponseResult<Boolean> aNew = servicePriceClient.isNew(priceRuleIsNewRequest);
		if (aNew.getData() == null) {
			return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_CHANGED.getCode(), CommonStatusEnum.PRICE_RULE_CHANGED.getValue());
		}

		// 设置key，看原来有没有key
		// Long increment = redisTemplate.opsForValue().increment(deviceCodeKey);

		// redisTemplate.opsForValue().setIfAbsent(deviceCodeKey,"1");

		// 判断下单设备是否是黑名单设备
		if (isBlackDevice(orderRequest)) {
			return ResponseResult.fail(CommonStatusEnum.DEVICE_IS_BLACK.getCode(), CommonStatusEnum.DEVICE_IS_BLACK.getValue());
		}

		// 判断下单的城市和计价规则是否正常
		if (!isPriceRuleExists(orderRequest)) {
			return ResponseResult.fail(CommonStatusEnum.CITY_SERVICE_NOT_SERVICE.getCode(), CommonStatusEnum.CITY_SERVICE_NOT_SERVICE.getValue());
		}

		// 判断是否有进行中的订单
		if (isPassengerOrderGoingon(orderRequest.getPassengerId()) > 0) {
			return ResponseResult.fail(CommonStatusEnum.ORDER_GOING_ON.getCode(), CommonStatusEnum.ORDER_GOING_ON.getValue());
		}
		// 创建订单
		OrderInfo orderInfo = new OrderInfo();
		BeanUtils.copyProperties(orderRequest, orderInfo);
		orderInfo.setOrderStatus(OrderConstants.ORDER_START);
		LocalDateTime now = LocalDateTime.now();
		orderInfo.setGmtCreate(now);
		orderInfo.setGmtModified(now);
		orderInfoMapper.insert(orderInfo);

		// 派单
		// 定时任务的处理
		for (int i = 0; i < 30; i++) {
			// 派单 dispatchRealTimeOrder
			int result = dispatchRealTimeOrder(orderInfo);
			if (result == 1) {
				break;
			}
			if (i == 29) {
				// 订单无效
				orderInfo.setOrderStatus(OrderConstants.ORDER_INVALID);
				orderInfoMapper.updateById(orderInfo);
				return ResponseResult.fail(CommonStatusEnum.ORDER_NOT_HAVE_DRIVER.getCode(), CommonStatusEnum.ORDER_NOT_HAVE_DRIVER.getValue());
			} else {
				// 等待20s
				try {
					Thread.sleep(2);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

		return ResponseResult.success();
	}

	/**
	 * 实时订单派单逻辑
	 *
	 * @param orderInfo
	 * @return
	 */
	public int dispatchRealTimeOrder(OrderInfo orderInfo) {
		log.info("循环一次");
		int result = 0;
		// 	2KM
		String depLatitude = orderInfo.getDepLatitude();
		String depLongitude = orderInfo.getDepLongitude();
		String center = depLatitude + "," + depLongitude;
		ArrayList<Integer> radiusList = new ArrayList<>();
		radiusList.add(2000);
		radiusList.add(4000);
		radiusList.add(5000);

		ResponseResult<List<TerminalResponse>> listResponseResult = null;
		radius:
		for (int i = 0; i < radiusList.size(); i++) {
			Integer radius = radiusList.get(i);
			listResponseResult = serviceMapClient.aroundSearch(center, radius);

			// log.info("在半径为" + radius + "的范围内，寻找车辆，结果" + JSONArray.fromObject(listResponseResult.getData().toString()));

			// 	获得终端

			// 	解析终端
			// JSONArray result = JSONArray.fromObject(listResponseResult.getData());
			List<TerminalResponse> data = listResponseResult.getData();

			for (int j = 0; j < data.size(); j++) {
				TerminalResponse terminalResponse = data.get(j);
				Long carId = terminalResponse.getCarId();

				String longitude = terminalResponse.getLongitude();
				String latitude = terminalResponse.getLatitude();

				// 查询是否有对应的可派单司机
				ResponseResult<OrderDriverResponse> availableDriver = serviceDriverUserClient.getAvailableDriver(carId);
				if (availableDriver.getCode() == CommonStatusEnum.AVAILABLE_DRIVER_EMPTY.getCode()) {
					log.info("没有车辆ID：" + carId + ",对于的司机");
					continue;
				} else {
					log.info("车辆ID：" + carId + "找到了正在出车的司机");

					OrderDriverResponse orderDriverResponse = availableDriver.getData();
					Long driverId = orderDriverResponse.getDriverId();
					String driverPhone = orderDriverResponse.getDriverPhone();
					String licenseId = orderDriverResponse.getLicenseId();
					String vehicleNo = orderDriverResponse.getVehicleNo();
					String vehicleTypeFromCar = orderDriverResponse.getVehicleType();

					// 判断车辆的车型是否符合？
					String vehicleType = orderInfo.getVehicleType();
					if (!vehicleType.trim().equals(vehicleTypeFromCar.trim())) {
						System.out.println("车型不符合");
						continue;
					}

					String lockKey = (driverId + "").intern();
					RLock lock = redissonClient.getLock(lockKey);
					lock.lock();

					// 判断司机 是否有进行中的订单
					if (isDriverOrderGoingon(driverId) > 0) {
						lock.unlock();
						continue;
					}
					// 订单直接匹配司机
					// 查询当前车辆信息
					QueryWrapper<Car> carQueryWrapper = new QueryWrapper<>();
					carQueryWrapper.eq("id", carId);


					// 设置订单中和司机车辆相关的信息
					orderInfo.setDriverId(driverId);
					orderInfo.setDriverPhone(driverPhone);
					orderInfo.setCarId(carId);
					// 从地图中来
					orderInfo.setReceiveOrderCarLongitude(longitude);
					orderInfo.setReceiveOrderCarLatitude(latitude);

					orderInfo.setReceiveOrderTime(LocalDateTime.now());
					orderInfo.setLicenseId(licenseId);
					orderInfo.setVehicleNo(vehicleNo);
					orderInfo.setOrderStatus(OrderConstants.DRIVER_RECEIVE_ORDER);

					orderInfoMapper.updateById(orderInfo);

					// 通知司机
					JSONObject driverContent = new JSONObject();

					driverContent.put("orderId", orderInfo.getId());
					driverContent.put("passengerId", orderInfo.getPassengerId());
					driverContent.put("passengerPhone", orderInfo.getPassengerPhone());
					driverContent.put("departure", orderInfo.getDeparture());
					driverContent.put("depLongitude", orderInfo.getDepLongitude());
					driverContent.put("depLatitude", orderInfo.getDepLatitude());

					driverContent.put("destination", orderInfo.getDestination());
					driverContent.put("destLongitude", orderInfo.getDestLongitude());
					driverContent.put("destLatitude", orderInfo.getDestLatitude());


					send(driverId, IdentityConstant.DRIVER_IDENTITY, driverContent.toString());

					// 通知乘客
					JSONObject passengerContent = new JSONObject();
					passengerContent.put("orderId", orderInfo.getId());
					passengerContent.put("driverId", orderInfo.getDriverId());
					passengerContent.put("driverPhone", orderInfo.getDriverPhone());
					passengerContent.put("vehicleNo", orderInfo.getVehicleNo());
					// 车辆信息，调用车辆服务
					ResponseResult<Car> carById = serviceDriverUserClient.getCarById(carId);
					Car carRemote = carById.getData();

					passengerContent.put("brand", carRemote.getBrand());
					passengerContent.put("model", carRemote.getModel());
					passengerContent.put("vehicleColor", carRemote.getVehicleColor());

					passengerContent.put("receiveOrderCarLongitude", orderInfo.getReceiveOrderCarLongitude());
					passengerContent.put("receiveOrderCarLatitude", orderInfo.getReceiveOrderCarLatitude());

					send(orderInfo.getPassengerId(), IdentityConstant.PASSENGER_IDENTITY, passengerContent.toString());

					result = 1;
					lock.unlock();
					break radius;
				}
			}
		}
		return result;
	}

	/**
	 * 接乘客
	 *
	 * @param orderRequest
	 * @return
	 */
	@Override
	public ResponseResult toPickUpPassenger(OrderRequest orderRequest) {
		Long orderId = orderRequest.getOrderId();
		LocalDateTime toPickUpPassengerTime = orderRequest.getToPickUpPassengerTime();
		String toPickUpPassengerLongitude = orderRequest.getToPickUpPassengerLongitude();
		String toPickUpPassengerLatitude = orderRequest.getToPickUpPassengerLatitude();
		String toPickUpPassengerAddress = orderRequest.getToPickUpPassengerAddress();
		QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("id", orderId);
		OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);

		orderInfo.setToPickUpPassengerAddress(toPickUpPassengerAddress);
		orderInfo.setToPickUpPassengerTime(toPickUpPassengerTime);
		orderInfo.setToPickUpPassengerLongitude(toPickUpPassengerLongitude);
		orderInfo.setToPickUpPassengerLatitude(toPickUpPassengerLatitude);
		orderInfo.setOrderStatus(OrderConstants.DRIVER_TO_PICK_UP_PASSENGER);

		orderInfoMapper.updateById(orderInfo);
		return ResponseResult.success();
	}

	/**
	 * 司机到达乘客上车点
	 *
	 * @param orderRequest
	 * @return
	 */
	@Override
	public ResponseResult arrivedDeparture(OrderRequest orderRequest) {
		Long orderId = orderRequest.getOrderId();

		QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("id", orderId);

		OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
		orderInfo.setOrderStatus(OrderConstants.DRIVER_ARRIVED_DEPARTURE);

		orderInfo.setDriverArrivedDepartureTime(LocalDateTime.now());
		orderInfoMapper.updateById(orderInfo);
		return ResponseResult.success();
	}

	/**
	 * 司机接到乘客
	 *
	 * @param orderRequest
	 * @return
	 */
	@Override
	public ResponseResult pickUpPassenger(OrderRequest orderRequest) {
		Long orderId = orderRequest.getOrderId();

		QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("id", orderId);
		OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);

		orderInfo.setPickUpPassengerLongitude(orderRequest.getPickUpPassengerLongitude());
		orderInfo.setPickUpPassengerLatitude(orderRequest.getPickUpPassengerLatitude());
		orderInfo.setPickUpPassengerTime(LocalDateTime.now());
		orderInfo.setOrderStatus(OrderConstants.PICK_UP_PASSENGER);

		orderInfoMapper.updateById(orderInfo);
		return ResponseResult.success();
	}

	/**
	 * 乘客下车到达目的地，行程终止
	 *
	 * @param orderRequest
	 * @return
	 */
	@Override
	public ResponseResult passengerGetoff(OrderRequest orderRequest) {
		Long orderId = orderRequest.getOrderId();

		QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("id", orderId);
		OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);

		orderInfo.setPassengerGetoffTime(LocalDateTime.now());
		orderInfo.setPassengerGetoffLongitude(orderRequest.getPassengerGetoffLongitude());
		orderInfo.setPassengerGetoffLatitude(orderRequest.getPassengerGetoffLatitude());

		orderInfo.setOrderStatus(OrderConstants.PASSENGER_GETOFF);
		// 订单行驶的路程和时间,调用 service-map
		ResponseResult<Car> carById = serviceDriverUserClient.getCarById(orderInfo.getCarId());
		Long starttime = orderInfo.getPickUpPassengerTime().toInstant(ZoneOffset.of("+8")).toEpochMilli();
		Long endtime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
		System.out.println("开始时间：" + starttime);
		System.out.println("结束时间：" + endtime);
		// 1668078028000l,测试的时候不要跨天
		ResponseResult<TrsearchResponse> trsearch = serviceMapClient.trsearch(carById.getData().getTid(), starttime, endtime);
		TrsearchResponse data = trsearch.getData();
		Long driveMile = data.getDriveMile();
		Long driveTime = data.getDriveTime();

		orderInfo.setDriveMile(driveMile);
		orderInfo.setDriveTime(driveTime);

		// 获取价格
		String address = orderInfo.getAddress();
		String vehicleType = orderInfo.getVehicleType();
		ResponseResult<Double> doubleResponseResult = servicePriceClient.calculatePrice(driveMile.intValue(), driveTime.intValue(), address, vehicleType);
		Double price = doubleResponseResult.getData();
		orderInfo.setPrice(price);

		orderInfoMapper.updateById(orderInfo);
		return ResponseResult.success();
	}

	/**
	 * 司机发起收款
	 *
	 * @param orderRequest
	 * @return
	 */
	@Override
	public ResponseResult pushPayInfo(OrderRequest orderRequest) {
		Long orderId = orderRequest.getOrderId();

		OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
		orderInfo.setOrderStatus(OrderConstants.TO_START_PAY);
		orderInfoMapper.updateById(orderInfo);
		return ResponseResult.success();
	}

	@Override
	public ResponseResult pay(OrderRequest orderRequest) {
		Long orderId = orderRequest.getOrderId();
		OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
		orderInfo.setOrderStatus(OrderConstants.OVER_PAY);
		orderInfoMapper.updateById(orderInfo);
		return ResponseResult.success();
	}

	@Override
	public ResponseResult cancel(Long orderId, String identity) {
		// 查询订单当前状态
		OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
		Integer orderStatus = orderInfo.getOrderStatus();

		LocalDateTime cancelTime = LocalDateTime.now();
		Integer cancelOperator = null;
		Integer cancelTypeCode = null;

		// 正常取消
		int cancelType = 1;

		// 更新订单的取消状态
		// 如果是乘客取消
		if (identity.trim().equals(IdentityConstant.PASSENGER_IDENTITY)){
			switch (orderStatus){
				// 订单开始
				case OrderConstants.ORDER_START:
					cancelTypeCode = OrderConstants.CANCEL_PASSENGER_BEFORE;
					break;
				// 司机接到订单
				case OrderConstants.DRIVER_RECEIVE_ORDER:
					LocalDateTime receiveOrderTime = orderInfo.getReceiveOrderTime();
					long between = ChronoUnit.MINUTES.between(receiveOrderTime, cancelTime);
					if (between > 1){
						cancelTypeCode = OrderConstants.CANCEL_PASSENGER_ILLEGAL;
					}else {
						cancelTypeCode = OrderConstants.CANCEL_PASSENGER_BEFORE;
					}
					break;
				// 司机去接乘客
				case OrderConstants.DRIVER_TO_PICK_UP_PASSENGER:
					// 走完这里不break 会走下个case所以都汇总到下一个case了
					// cancelTypeCode = OrderConstants.CANCEL_PASSENGER_ILLEGAL;
					// 司机到达乘客起点
				case OrderConstants.DRIVER_ARRIVED_DEPARTURE:
					cancelTypeCode = OrderConstants.CANCEL_PASSENGER_ILLEGAL;
					break;
				default:
					log.info("乘客取消失败");
					cancelType = 0;
					break;
			}
		}

		// 如果是司机取消
		if (identity.trim().equals(IdentityConstant.DRIVER_IDENTITY)){
			switch (orderStatus){
				// 订单开始
				// 司机接到乘客
				case OrderConstants.DRIVER_RECEIVE_ORDER:
				case OrderConstants.DRIVER_TO_PICK_UP_PASSENGER:
				case OrderConstants.DRIVER_ARRIVED_DEPARTURE:
					LocalDateTime receiveOrderTime = orderInfo.getReceiveOrderTime();
					long between = ChronoUnit.MINUTES.between(receiveOrderTime, cancelTime);
					if (between > 1){
						cancelTypeCode = OrderConstants.CANCEL_DRIVER_ILLEGAL;
					}else {
						cancelTypeCode = OrderConstants.CANCEL_DRIVER_BEFORE;
					}
					break;

				default:
					log.info("司机取消失败");
					cancelType = 0;
					break;
			}
		}


		if (cancelType == 0){
			return ResponseResult.fail(CommonStatusEnum.ORDER_CANCEL_ERROR.getCode(),CommonStatusEnum.ORDER_CANCEL_ERROR.getValue());
		}

		orderInfo.setCancelTypeCode(cancelTypeCode);
		orderInfo.setCancelTime(cancelTime);
		orderInfo.setCancelOperator(Integer.parseInt(identity));
		orderInfo.setOrderStatus(OrderConstants.ORDER_CANCEL);

		orderInfoMapper.updateById(orderInfo);
		return ResponseResult.success();
	}

	@Override
	public ResponseResult book(OrderRequest orderRequest) {
		// 创建订单
		OrderInfo orderInfo = new OrderInfo();

		BeanUtils.copyProperties(orderRequest,orderInfo);

		orderInfo.setOrderStatus(OrderConstants.ORDER_START);

		LocalDateTime now = LocalDateTime.now();
		orderInfo.setGmtCreate(now);
		orderInfo.setGmtModified(now);

		orderInfoMapper.insert(orderInfo);

		// 定时任务的处理
		for (int i =0;i<6;i++){
			// 派单 dispatchRealTimeOrder
			int result = dispatchBookOrder(orderInfo);
			if (result == 1){
				break;
			}

			// 等待20s
			try {
				Thread.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		return ResponseResult.success();
	}

	@Override
	public ResponseResult<OrderInfo> detail(Long orderId) {
		OrderInfo orderInfo =  orderInfoMapper.selectById(orderId);
		return ResponseResult.success(orderInfo);
	}

	@Override
	public ResponseResult current(String phone, String identity) {
		QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();

		if (identity.equals(IdentityConstant.DRIVER_IDENTITY)){
			queryWrapper.eq("driver_phone",phone);

			queryWrapper.and(wrapper->wrapper
					.eq("order_status",OrderConstants.DRIVER_RECEIVE_ORDER)
					.or().eq("order_status",OrderConstants.DRIVER_TO_PICK_UP_PASSENGER)
					.or().eq("order_status",OrderConstants.DRIVER_ARRIVED_DEPARTURE)
					.or().eq("order_status",OrderConstants.PICK_UP_PASSENGER)

			);
		}
		if (identity.equals(IdentityConstant.PASSENGER_IDENTITY)){
			queryWrapper.eq("passenger_phone",phone);
			queryWrapper.and(wrapper->wrapper.eq("order_status",OrderConstants.ORDER_START)
					.or().eq("order_status",OrderConstants.DRIVER_RECEIVE_ORDER)
					.or().eq("order_status",OrderConstants.DRIVER_TO_PICK_UP_PASSENGER)
					.or().eq("order_status",OrderConstants.DRIVER_ARRIVED_DEPARTURE)
					.or().eq("order_status",OrderConstants.PICK_UP_PASSENGER)
					.or().eq("order_status",OrderConstants.PASSENGER_GETOFF)
					.or().eq("order_status",OrderConstants.TO_START_PAY)
			);
		}

		OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
		return ResponseResult.success(orderInfo);
	}

	/**
	 * 通知司机和乘客订单信息
	 *
	 * @param id
	 * @param identity
	 * @param message
	 */
	public void send(Long id, String identity, String message) {
		PushRequest pushRequest = new PushRequest();
		pushRequest.setUserId(id);
		pushRequest.setIdentity(identity);
		pushRequest.setContent(message);

		serviceSsePushClient.push(pushRequest);
	}

	/**
	 * 计价规则是否存在
	 *
	 * @param orderRequest
	 * @return
	 */
	private boolean isPriceRuleExists(OrderRequest orderRequest) {
		String fareType = orderRequest.getFareType();
		int index = fareType.indexOf("$");
		String cityCode = fareType.substring(0, index);
		String vehicleType = fareType.substring(index + 1);

		PriceRule priceRule = new PriceRule();
		priceRule.setCityCode(cityCode);
		priceRule.setVehicleType(vehicleType);

		ResponseResult<Boolean> booleanResponseResult = servicePriceClient.ifExists(priceRule);
		return booleanResponseResult.getData();
	}

	/**
	 * 判断是否存在 业务中的订单
	 *
	 * @param passengerId
	 * @return
	 */
	private int isPassengerOrderGoingon(Long passengerId) {
		// 判断有正在进行的订单不允许下单
		QueryWrapper<OrderInfo> querywrapper = new QueryWrapper<>();
		querywrapper.eq("passenger_id", passengerId);
		querywrapper.and(wrapper -> wrapper.eq("order_status", OrderConstants.ORDER_START)
				.or().eq("order_status", OrderConstants.DRIVER_RECEIVE_ORDER)
				.or().eq("order_status", OrderConstants.DRIVER_TO_PICK_UP_PASSENGER)
				.or().eq("order_status", OrderConstants.DRIVER_ARRIVED_DEPARTURE)
				.or().eq("order_status", OrderConstants.PICK_UP_PASSENGER)
				.or().eq("order_status", OrderConstants.PASSENGER_GETOFF)
				.or().eq("order_status", OrderConstants.TO_START_PAY)
		);

		Integer count = orderInfoMapper.selectCount(querywrapper);
		return count;
	}

	/**
	 * 是否是黑名单
	 *
	 * @param orderRequest
	 * @return
	 */
	private boolean isBlackDevice(OrderRequest orderRequest) {

		// 需要判断 下单的设备是否是黑名单设备
		String deviceCode = orderRequest.getDeviceCode();
		// 生成key
		String deviceCodeKey = RedisPrefixUtils.blackDeviceCodePrefix + deviceCode;

		Boolean aBoolean = redisTemplate.hasKey(deviceCodeKey);
		if (aBoolean) {
			String s = redisTemplate.opsForValue().get(deviceCodeKey);
			int i = Integer.parseInt(s);
			if (i > 2) {
				// 	当前设备超过下单次数
				return true;
			} else {
				redisTemplate.opsForValue().increment(deviceCodeKey);
			}
		} else {
			redisTemplate.opsForValue().setIfAbsent(deviceCodeKey, "1", 1L, TimeUnit.HOURS);
		}
		return false;
	}

	/**
	 * 判断是否有 业务中的订单
	 *
	 * @param driverId
	 * @return
	 */
	private int isDriverOrderGoingon(Long driverId) {
		// 判断有正在进行的订单不允许下单
		QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("driver_id", driverId);
		queryWrapper.and(wrapper -> wrapper
				.eq("order_status", OrderConstants.DRIVER_RECEIVE_ORDER)
				.or().eq("order_status", OrderConstants.DRIVER_TO_PICK_UP_PASSENGER)
				.or().eq("order_status", OrderConstants.DRIVER_ARRIVED_DEPARTURE)
				.or().eq("order_status", OrderConstants.PICK_UP_PASSENGER)

		);


		Integer validOrderNumber = orderInfoMapper.selectCount(queryWrapper);
		log.info("司机Id：" + driverId + ",正在进行的订单的数量：" + validOrderNumber);

		return validOrderNumber;

	}

	/**
	 * 预约订单-分发订单
	 * 如果返回1：派单成功
	 * @param orderInfo
	 */
	public int dispatchBookOrder(OrderInfo orderInfo){
		log.info("循环一次 book");
		int result = 0;

		//2km
		String depLatitude = orderInfo.getDepLatitude();
		String depLongitude = orderInfo.getDepLongitude();

		String center = depLatitude+","+depLongitude;

		List<Integer> radiusList = new ArrayList<>();
		radiusList.add(2000);
		radiusList.add(4000);
		radiusList.add(5000);
		// 搜索结果
		ResponseResult<List<TerminalResponse>> listResponseResult = null;
		// goto是为了测试。
		radius:
		for (int i=0;i<radiusList.size();i++){
			Integer radius = radiusList.get(i);
			listResponseResult = serviceMapClient.aroundSearch(center,radius );

			log.info("在半径为"+radius+"的范围内，寻找车辆,结果："+ JSONArray.fromObject(listResponseResult.getData()).toString());

			// 获得终端  [{"carId":1578641048288702465,"tid":"584169988"}]

			// 解析终端-真实代码
			List<TerminalResponse> data = listResponseResult.getData();
			// 测试：为了测试是否从地图上获取到司机
//            TerminalResponse testTerminal = new TerminalResponse();
//            testTerminal.setCarId(6l);
//            testTerminal.setTid("738109731");
//            testTerminal.setLatitude("39.907321");
//            testTerminal.setLongitude("116.395111");
//            List<TerminalResponse> data = new ArrayList<>();
//            data.add(testTerminal);

			for (int j=0;j<data.size();j++){
				TerminalResponse terminalResponse = data.get(j);
				Long carId = terminalResponse.getCarId();

				String longitude = terminalResponse.getLongitude();
				String latitude = terminalResponse.getLatitude();

				// 查询是否有对应的可派单司机
				ResponseResult<OrderDriverResponse> availableDriver = serviceDriverUserClient.getAvailableDriver(carId);
				if(availableDriver.getCode() == CommonStatusEnum.AVAILABLE_DRIVER_EMPTY.getCode()){
					log.info("没有车辆ID："+carId+",对于的司机");
					continue;
				}else {
					log.info("车辆ID："+carId+"找到了正在出车的司机");

					OrderDriverResponse orderDriverResponse = availableDriver.getData();
					Long driverId = orderDriverResponse.getDriverId();
					String driverPhone = orderDriverResponse.getDriverPhone();
					String licenseId = orderDriverResponse.getLicenseId();
					String vehicleNo = orderDriverResponse.getVehicleNo();
					String vehicleTypeFromCar = orderDriverResponse.getVehicleType();

					// 判断车辆的车型是否符合？
					String vehicleType = orderInfo.getVehicleType();
					if (!vehicleType.trim().equals(vehicleTypeFromCar.trim())){
						System.out.println("车型不符合");
						continue ;
					}

					// 通知司机
					JSONObject driverContent = new  JSONObject();

					driverContent.put("orderId",orderInfo.getId());
					driverContent.put("passengerId",orderInfo.getPassengerId());
					driverContent.put("passengerPhone",orderInfo.getPassengerPhone());
					driverContent.put("departure",orderInfo.getDeparture());
					driverContent.put("depLongitude",orderInfo.getDepLongitude());
					driverContent.put("depLatitude",orderInfo.getDepLatitude());

					driverContent.put("destination",orderInfo.getDestination());
					driverContent.put("destLongitude",orderInfo.getDestLongitude());
					driverContent.put("destLatitude",orderInfo.getDestLatitude());

					PushRequest pushRequest = new PushRequest();
					pushRequest.setUserId(driverId);
					pushRequest.setIdentity(IdentityConstant.DRIVER_IDENTITY);
					pushRequest.setContent(driverContent.toString());

					serviceSsePushClient.push(pushRequest);
					result = 1;

					// 退出，不在进行 司机的查找.如果派单成功，则退出循环
					break radius;
				}

			}

		}

		return  result;

	}
}
